package server;

/*
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 * ActinoServer.java
 *
 * Steven Louie Apr. 8, 2012
 *
 */
import client.ActinoClient;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import java.io.IOException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.life.ActinoNPC;
import server.net.*;

public class ActinoServer implements Runnable {

    private static final int PORT = 5050;
    private static ActinoServer instance = null;
    private Server server;
    private HashMap<Connection, ActinoClient> clients = new HashMap<>();
    private int clientCount = 0;

    private ActinoServer() {
        server = new Server();
        Network.register(server);

        try {
            server.bind(PORT);
        } catch (IOException ex) {
            Logger.getLogger(ActinoServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        server.start();

        server.addListener(new Listener() {

            @Override
            public void connected(Connection c) {
                clients.put(c, new ActinoClient(c));
                clientCount++;
            }

            @Override
            public void received(Connection c, Object object) {
                if (object instanceof ChatMessage) {
                    System.out.print("CHAT: ");
                    ChatMessage msg = (ChatMessage) object;
                    System.out.print("type: " + msg.type);
                    System.out.print("; source: " + msg.source);
                    System.out.println("; text: " + msg.text);
                    server.sendToAllTCP(msg);
                }

                if (object instanceof MovementAction) {
                    MovementAction mvt = (MovementAction) object;
                    server.sendToAllExceptTCP(c.getID(), mvt);
                }

                if (object instanceof LoginAction) {
                    LoginAction login = (LoginAction) object;
                    int result = clients.get(c).login(login.username, login.password);
                    login.state = result;
                    if (result != 1) {
                        server.sendToTCP(c.getID(), login);
                    } else {
                        System.out.println(c + " logged in: " + c.getRemoteAddressTCP().getAddress()
                                + "/" + login.username);
                        // Should send initial player data here
                        server.sendToTCP(c.getID(), login);
                    }
                }
                
                if (object instanceof NPCInteraction) {
                    NPCInteraction npc = (NPCInteraction) object;
                    new ActinoNPC("test", npc.npc).interact(clients.get(c), clients.get(c).getPlayer());
                }
            }

            @Override
            public void disconnected(Connection c) {
                clients.get(c).disconnect();
                clients.remove(c);
                clientCount--;
            }
        });
    }

    public static ActinoServer getInstance() {
        if (instance == null) {
            instance = new ActinoServer();
        }
        return instance;
    }

    public Server getServer() {
        return server;
    }
    
    @Override
    public void run() {
    }

    public static void main(String[] args) {
        ActinoServer.getInstance().run();
    }
}
